<template>
  <div id="addDept">
    <el-dialog
      :title="form.id ? '编辑部门' : '新增部门'"
      :visible="dialogShow"
      :close-on-click-modal="false"
      :close-on-press-escape="true"
      @close="cancel"
    >
      <el-form ref="myform" :model="form" :rules="rules" class="el-form">
        <el-form-item prop="name" label="部门名称">
          <el-input v-model="form.name" />
        </el-form-item>
        <el-form-item prop="code" label="部门编码">
          <el-input v-model="form.code" />
        </el-form-item>
        <el-form-item prop="manager" label="部门负责人">
          <!-- <el-input v-model="form.manager" /> 因为项目模板中的是下拉框，所以要修改结构 -->
          <el-select v-model="form.manager" placeholder="请选择部门管理员">
            <el-option
              v-for="item in managerList"
              :key="item.id"
              :label="item.username"
              :value="item.username"
            />
          </el-select>
        </el-form-item>
        <el-form-item prop="introduce" label="部门介绍">
          <el-input v-model="form.introduce" />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog_btn">
        <el-button @click="cancel">取消</el-button>
        <el-button type="primary" @click="submit">确定</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
// 导入操作数据的接口
import {
  deptListAPI,
  administratorAPI,
  addDeptAPI,
  getDeptDetailAPI,
  editDeptAPI
} from '@/api/index'
export default {
  // 从外界接收参数 控制面板的显示与隐藏
  props: ['dialogShow', 'currentId'],
  data() {
    return {
      form: {
        code: '', // 部门编码
        introduce: '', // 部门介绍
        manager: '', // 部门负责人
        name: '', // 部门名称
        pid: '' // 父级部门
      },
      rules: {
        name: [
          { required: true, message: '请输入部门名称' },
          { min: 1, max: 50, message: '长度在1~50个字符之间' },
          // 添加自定义校验规则
          {
            validator: async(rules, value, callback) => {
              // 1.0 得到所有的部门数据
              const res = await deptListAPI()
              if (!this.form.id) {
                // 新增部门的校验规则
                // 2.0 根据当前操作部门的 id 得到所有的子部门
                const newArr = res.data.depts.filter((item) => {
                  return item.pid === this.currentId
                })
                // 3.0 判断子部门中是否存在名称相同的部门
                const bool = newArr.some((item) => {
                  return item.name === value
                })
                // 存在同名部门时就报错，不存在就通过校验
                bool ? callback(new Error('同级部门名称不能重复')) : callback()
              } else {
                // 编辑部门额校验规则
                // 2. 根据当前操作的部门，得到所有的同级部门
                const newArr = res.data.depts.filter((item) => {
                  return item.pid === this.form.pid
                })
                // 3. 判断统计部门中名称是否冲突
                const bool = newArr.some((item) => {
                  return item.name === value && item.id !== this.form.id
                })
                // 存在同名部门时就报错，不存在就通过校验
                bool ? callback(new Error('同级部门名称不能重复')) : callback()
              }
            },
            trigger: 'blur'
          }
        ],
        code: [
          { required: true, message: '请输入部门编码' },
          { min: 1, max: 25, message: '长度在1~25个字符之间' },
          {
            validator: async(rule, value, callback) => {
              //   得到所有的部门数据
              const res = await deptListAPI()
              if (!this.form.id) {
                const bool = res.data.depts.some((item) => {
                  return item.code === value
                })
                //   存在相同部门编码就报错，不存在就通过验证
                bool ? callback(new Error('部门编码不能重复')) : callback()
              } else {
                // 得到所有的部门数据
                const res = await deptListAPI()
                // 遍历数据，判断是否存在与 value 相同的 code （除掉自己）
                const bool = res.data.depts.some((item) => {
                  return item.code === value && item.id !== this.form.id
                })
                // 判断
                bool ? callback(new Error('部门编码不能重复')) : callback()
              }
            },
            trigger: 'blur'
          }
        ],
        introduce: [
          { required: true, message: '请输入部门介绍' },
          { min: 1, max: 50, message: '长度在1~50个字符之间' }
        ],
        manager: [
          { required: true, message: '请输入部门负责人' },
          { min: 1, max: 50, message: '长度在1~50个字符之间' }
        ]
      },
      // 保存负责人的数据源
      managerList: [],
      timerID: ''
    }
  },
  created() {
    // 页面加载完毕时调用 getAdministrator() 方法，渲染页面
    this.getAdministrator()
  },
  methods: {
    // 根据id获得部门详情数据
    async getDeptDetail(id) {
      // 发起请求
      const res = await getDeptDetailAPI(id)
      // 保存数据
      this.form = res.data
    },
    // 提交数据到服务器
    submit() {
      // 完成全局验证
      this.$refs.myform.validate(async(valid) => {
        if (valid) {
          if (!this.form.id) {
            // 新增操作
            // 给新增数据的pid赋值 (并判断是否添加的是一级部门)
            this.form.pid =
              this.currentId === '604e115c7bfcfa45d019d3e9'
                ? ''
                : this.currentId
            // 提交数据到服务器
            await addDeptAPI(this.form)
          } else {
            // 修改操作
            // 提交数据到服务器
            await editDeptAPI(this.form)
          }
          // 关闭新增面板
          this.$emit('hideDialog')
          // 提示新增成功
          this.$message.success(
            this.form.id ? '修改部门信息成功' : '新增部门信息成功'
          )
          // 清空表单
          this.form = {
            code: '', // 部门编码
            introduce: '', // 部门介绍
            manager: '', // 部门负责人
            name: '', // 部门名称
            pid: '' // 父级部门
          }
          // 更新页面数据
          this.$emit('updatedata')
        } else {
          this.$message.error('请输入符合要求的内容')
        }
      })
    },
    cancel() {
      // 由于dialogShow是从父组件中传进来的，直接在子组件修改就会报错，这种报错叫做单向数据流
      this.$emit('hideDialog')
      // 想要使用.sync语法简化父组件代码，还需要修改传递数据的代码
      // this.$emit('update:dialogShow', false) // 数据传递时顺便把要修改的值传过去

      this.timerID = setTimeout(() => {
        clearTimeout(this.timerID)
        // 关闭时清除表单上的数据
        // 清空表单
        this.form = {
          code: '', // 部门编码
          introduce: '', // 部门介绍
          manager: '', // 部门负责人
          name: '', // 部门名称
          pid: '' // 父级部门
        }
        // 重置表单的校验规则
        this.$refs.myform.resetFields()
      }, 350)
    },
    async getAdministrator() {
      // 获取各部门负责人信息
      const res = await administratorAPI()
      // 将获取到的数据赋值给数组，并将其渲染到页面上
      this.managerList = res.data
    }
  }
}
</script>

<style lang="scss">
#addDept {
  .el-dialog {
    width: 40%;
    .el-dialog__body {
      padding: 15px 20px 0 40px;
    }
    .el-dialog__header {
      padding: 15px 20px 12px;
    }
    .el-form {
      width: 100%;
      .el-form-item__content {
        display: flex;
      }
    }
    .el-dialog__footer {
      margin-top: -5px;
      padding: 0 0 12px;
      .dialog_btn {
        text-align: center;
      }
    }
  }
}
</style>
